home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / interp / perl-5.003.tar.gz / perl-5.003.tar / perl-5.003 / lib / ExtUtils / MM_VMS.pm < prev    next >
Text File  |  1996-06-24  |  68KB  |  2,255 lines

  1. #   MM_VMS.pm
  2. #   MakeMaker default methods for VMS
  3. #   This package is inserted into @ISA of MakeMaker's MM before the
  4. #   built-in ExtUtils::MM_Unix methods if MakeMaker.pm is run under VMS.
  5. #
  6. #   Author:  Charles Bailey  bailey@genetics.upenn.edu
  7.  
  8. package ExtUtils::MM_VMS;
  9. $ExtUtils::MM_VMS::Revision=$ExtUtils::MM_VMS::Revision = '5.35 (23-Jun-1996)';
  10. unshift @MM::ISA, 'ExtUtils::MM_VMS';
  11.  
  12. use Config;
  13. require Exporter;
  14. use VMS::Filespec;
  15. use File::Basename;
  16.  
  17. Exporter::import('ExtUtils::MakeMaker', '$Verbose', '&neatvalue');
  18.  
  19. =head1 NAME
  20.  
  21. ExtUtils::MM_VMS - methods to override UN*X behaviour in ExtUtils::MakeMaker
  22.  
  23. =head1 SYNOPSIS
  24.  
  25.  use ExtUtils::MM_VMS; # Done internally by ExtUtils::MakeMaker if needed
  26.  
  27. =head1 DESCRIPTION
  28.  
  29. See ExtUtils::MM_Unix for a documentation of the methods provided
  30. there. This package overrides the implementation of these methods, not
  31. the semantics.
  32.  
  33. =head2 Methods always loaded
  34.  
  35. =item eliminate_macros
  36.  
  37. Expands MM[KS]/Make macros in a text string, using the contents of
  38. identically named elements of C<%$self>, and returns the result
  39. as a file specification in Unix syntax.
  40.  
  41. =cut
  42.  
  43. sub eliminate_macros {
  44.     my($self,$path) = @_;
  45.     unless ($path) {
  46.     print "eliminate_macros('') = ||\n" if $Verbose >= 3;
  47.     return '';
  48.     }
  49.     my($npath) = unixify($path);
  50.     my($head,$macro,$tail);
  51.  
  52.     # perform m##g in scalar context so it acts as an iterator
  53.     while ($npath =~ m#(.*?)\$\((\S+?)\)(.*)#g) { 
  54.         if ($self->{$2}) {
  55.             ($head,$macro,$tail) = ($1,$2,$3);
  56.             ($macro = unixify($self->{$macro})) =~ s#/$##;
  57.             $npath = "$head$macro$tail";
  58.         }
  59.     }
  60.     print "eliminate_macros($path) = |$npath|\n" if $Verbose >= 3;
  61.     $npath;
  62. }
  63.  
  64. =item fixpath
  65.  
  66. Catchall routine to clean up problem MM[SK]/Make macros.  Expands macros
  67. in any directory specification, in order to avoid juxtaposing two
  68. VMS-syntax directories when MM[SK] is run.  Also expands expressions which
  69. are all macro, so that we can tell how long the expansion is, and avoid
  70. overrunning DCL's command buffer when MM[KS] is running.
  71.  
  72. If optional second argument has a TRUE value, then the return string is
  73. a VMS-syntax directory specification, otherwise it is a VMS-syntax file
  74. specification.
  75.  
  76. =cut
  77.  
  78. sub fixpath {
  79.     my($self,$path,$force_path) = @_;
  80.     unless ($path) {
  81.     print "eliminate_macros('') = ||\n" if $Verbose >= 3;
  82.     return '';
  83.     }
  84.     my($fixedpath,$prefix,$name);
  85.  
  86.     if ($path =~ m#^\$\(.+\)$# || $path =~ m#[/:>\]]#) { 
  87.         if ($force_path or $path =~ /(?:DIR\)|\])$/) {
  88.             $fixedpath = vmspath($self->eliminate_macros($path));
  89.         }
  90.         else {
  91.             $fixedpath = vmsify($self->eliminate_macros($path));
  92.         }
  93.     }
  94.     elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#)) && $self->{$prefix}) {
  95.         my($vmspre) = vmspath($self->{$prefix}) || ''; # is it a dir or just a name?
  96.         $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name;
  97.         $fixedpath = vmspath($fixedpath) if $force_path;
  98.     }
  99.     else {
  100.         $fixedpath = $path;
  101.         $fixedpath = vmspath($fixedpath) if $force_path;
  102.     }
  103.     # Convert names without directory or type to paths
  104.     if (!$force_path and $fixedpath !~ /[:>(.\]]/) { $fixedpath = vmspath($fixedpath); }
  105.     print "fixpath($path) = |$fixedpath|\n" if $Verbose >= 3;
  106.     $fixedpath;
  107. }
  108.  
  109. =item catdir
  110.  
  111. Concatenates a list of file specifications, and returns the result as a
  112. VMS-syntax directory specification.
  113.  
  114. =cut
  115.  
  116. sub catdir {
  117.     my($self,@dirs) = @_;
  118.     my($dir) = pop @dirs;
  119.     @dirs = grep($_,@dirs);
  120.     my($rslt);
  121.     if (@dirs) {
  122.       my($path) = (@dirs == 1 ? $dirs[0] : $self->catdir(@dirs));
  123.       my($spath,$sdir) = ($path,$dir);
  124.       $spath =~ s/.dir$//; $sdir =~ s/.dir$//; 
  125.       $sdir = $self->eliminate_macros($sdir) unless $sdir =~ /^[\w\-]+$/;
  126.       $rslt = vmspath($self->eliminate_macros($spath)."/$sdir");
  127.     }
  128.     else { $rslt = vmspath($dir); }
  129.     print "catdir(",join(',',@_[1..$#_]),") = |$rslt|\n" if $Verbose >= 3;
  130.     $rslt;
  131. }
  132.  
  133. =item catfile
  134.  
  135. Concatenates a list of file specifications, and returns the result as a
  136. VMS-syntax directory specification.
  137.  
  138. =cut
  139.  
  140. sub catfile {
  141.     my($self,@files) = @_;
  142.     my($file) = pop @files;
  143.     @files = grep($_,@files);
  144.     my($rslt);
  145.     if (@files) {
  146.       my($path) = (@files == 1 ? $files[0] : $self->catdir(@files));
  147.       my($spath) = $path;
  148.       $spath =~ s/.dir$//;
  149.       if ( $spath =~ /^[^\)\]\/:>]+\)$/ && basename($file) eq $file) { $rslt = "$spath$file"; }
  150.       else {
  151.           $rslt = $self->eliminate_macros($spath);
  152.           $rslt = vmsify($rslt.($rslt ? '/' : '').unixify($file));
  153.       }
  154.     }
  155.     else { $rslt = vmsify($file); }
  156.     print "catfile(",join(',',@_[1..$#_]),") = |$rslt|\n" if $Verbose >= 3;
  157.     $rslt;
  158. }
  159.  
  160. =item curdir (override)
  161.  
  162. Returns a string representing of the current directory.
  163.  
  164. =cut
  165.  
  166. sub curdir {
  167.     return '[]';
  168. }
  169.  
  170. =item rootdir (override)
  171.  
  172. Returns a string representing of the root directory.
  173.  
  174. =cut
  175.  
  176. sub rootdir {
  177.     return '';
  178. }
  179.  
  180. =item updir (override)
  181.  
  182. Returns a string representing of the parent directory.
  183.  
  184. =cut
  185.  
  186. sub updir {
  187.     return '[-]';
  188. }
  189.  
  190. package ExtUtils::MM_VMS;
  191.  
  192. sub ExtUtils::MM_VMS::guess_name;
  193. sub ExtUtils::MM_VMS::find_perl;
  194. sub ExtUtils::MM_VMS::path;
  195. sub ExtUtils::MM_VMS::maybe_command;
  196. sub ExtUtils::MM_VMS::maybe_command_in_dirs;
  197. sub ExtUtils::MM_VMS::perl_script;
  198. sub ExtUtils::MM_VMS::file_name_is_absolute;
  199. sub ExtUtils::MM_VMS::replace_manpage_separator;
  200. sub ExtUtils::MM_VMS::init_others;
  201. sub ExtUtils::MM_VMS::constants;
  202. sub ExtUtils::MM_VMS::const_loadlibs;
  203. sub ExtUtils::MM_VMS::cflags;
  204. sub ExtUtils::MM_VMS::const_cccmd;
  205. sub ExtUtils::MM_VMS::pm_to_blib;
  206. sub ExtUtils::MM_VMS::tool_autosplit;
  207. sub ExtUtils::MM_VMS::tool_xsubpp;
  208. sub ExtUtils::MM_VMS::xsubpp_version;
  209. sub ExtUtils::MM_VMS::tools_other;
  210. sub ExtUtils::MM_VMS::dist;
  211. sub ExtUtils::MM_VMS::c_o;
  212. sub ExtUtils::MM_VMS::xs_c;
  213. sub ExtUtils::MM_VMS::xs_o;
  214. sub ExtUtils::MM_VMS::top_targets;
  215. sub ExtUtils::MM_VMS::dlsyms;
  216. sub ExtUtils::MM_VMS::dynamic_lib;
  217. sub ExtUtils::MM_VMS::dynamic_bs;
  218. sub ExtUtils::MM_VMS::static_lib;
  219. sub ExtUtils::MM_VMS::manifypods;
  220. sub ExtUtils::MM_VMS::processPL;
  221. sub ExtUtils::MM_VMS::installbin;
  222. sub ExtUtils::MM_VMS::subdir_x;
  223. sub ExtUtils::MM_VMS::clean;
  224. sub ExtUtils::MM_VMS::realclean;
  225. sub ExtUtils::MM_VMS::dist_basics;
  226. sub ExtUtils::MM_VMS::dist_core;
  227. sub ExtUtils::MM_VMS::dist_dir;
  228. sub ExtUtils::MM_VMS::dist_test;
  229. sub ExtUtils::MM_VMS::install;
  230. sub ExtUtils::MM_VMS::perldepend;
  231. sub ExtUtils::MM_VMS::makefile;
  232. sub ExtUtils::MM_VMS::test;
  233. sub ExtUtils::MM_VMS::test_via_harness;
  234. sub ExtUtils::MM_VMS::test_via_script;
  235. sub ExtUtils::MM_VMS::makeaperl;
  236. sub ExtUtils::MM_VMS::ext;
  237. sub ExtUtils::MM_VMS::nicetext;
  238.  
  239. #use SelfLoader;
  240. sub AUTOLOAD {
  241.     my $code;
  242.     if (defined fileno(DATA)) {
  243.     my $fh = select DATA;
  244.     my $o = $/;            # For future reads from the file.
  245.     $/ = "\n__END__\n";
  246.     $code = <DATA>;
  247.     $/ = $o;
  248.     select $fh;
  249.     close DATA;
  250.     eval $code;
  251.     if ($@) {
  252.         $@ =~ s/ at .*\n//;
  253.         Carp::croak $@;
  254.     }
  255.     } else {
  256.     warn "AUTOLOAD called unexpectedly for $AUTOLOAD"; 
  257.     }
  258.     defined(&$AUTOLOAD) or die "Myloader inconsistency error";
  259.     goto &$AUTOLOAD;
  260. }
  261.  
  262. 1;
  263.  
  264. #__DATA__
  265.  
  266. =head2 SelfLoaded methods
  267.  
  268. Those methods which override default MM_Unix methods are marked
  269. "(override)", while methods unique to MM_VMS are marked "(specific)".
  270. For overridden methods, documentation is limited to an explanation
  271. of why this method overrides the MM_Unix method; see the ExtUtils::MM_Unix
  272. documentation for more details.
  273.  
  274. =item guess_name (override)
  275.  
  276. Try to determine name of extension being built.  We begin with the name
  277. of the current directory.  Since VMS filenames are case-insensitive,
  278. however, we look for a F<.pm> file whose name matches that of the current
  279. directory (presumably the 'main' F<.pm> file for this extension), and try
  280. to find a C<package> statement from which to obtain the Mixed::Case
  281. package name.
  282.  
  283. =cut
  284.  
  285. sub guess_name {
  286.     my($self) = @_;
  287.     my($defname,$defpm);
  288.     local *PM;
  289.  
  290.     $defname = basename(fileify($ENV{'DEFAULT'}));
  291.     $defname =~ s![\d\-_]*\.dir.*$!!;  # Clip off .dir;1 suffix, and package version
  292.     $defpm = $defname;
  293.     if (open(PM,"${defpm}.pm")){
  294.         while (<PM>) {
  295.             if (/^\s*package\s+([^;]+)/i) {
  296.                 $defname = $1;
  297.                 last;
  298.             }
  299.         }
  300.         print STDOUT "Warning (non-fatal): Couldn't find package name in ${defpm}.pm;\n\t",
  301.                      "defaulting package name to $defname\n"
  302.             if eof(PM);
  303.         close PM;
  304.     }
  305.     else {
  306.         print STDOUT "Warning (non-fatal): Couldn't find ${defpm}.pm;\n\t",
  307.                      "defaulting package name to $defname\n";
  308.     }
  309.     $defname =~ s#[\d.\-_]+$##;
  310.     $defname;
  311. }
  312.  
  313. =item find_perl (override)
  314.  
  315. Use VMS file specification syntax and CLI commands to find and
  316. invoke Perl images.
  317.  
  318. =cut
  319.  
  320. sub find_perl{
  321.     my($self, $ver, $names, $dirs, $trace) = @_;
  322.     my($name,$dir,$vmsfile,@sdirs,@snames,@cand);
  323.     # Check in relative directories first, so we pick up the current
  324.     # version of Perl if we're running MakeMaker as part of the main build.
  325.     @sdirs = sort { my($absb) = file_name_is_absolute($a);
  326.                     my($absb) = file_name_is_absolute($b);
  327.                     if ($absa && $absb) { return $a cmp $b }
  328.                     else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); }
  329.                   } @$dirs;
  330.     # Check miniperl before perl, and check names likely to contain
  331.     # version numbers before "generic" names, so we pick up an
  332.     # executable that's less likely to be from an old installation.
  333.     @snames = sort { my($ba) = $a =~ m!([^:>\]/]+)$!;  # basename
  334.                      my($bb) = $b =~ m!([^:>\]/]+)$!;
  335.                      substr($ba,0,1) cmp substr($bb,0,1)
  336.                      or -1*(length($ba) <=> length($bb)) } @$names;
  337.     if ($trace){
  338.     print "Looking for perl $ver by these names:\n";
  339.     print "\t@snames,\n";
  340.     print "in these dirs:\n";
  341.     print "\t@sdirs\n";
  342.     }
  343.     foreach $dir (@sdirs){
  344.     next unless defined $dir; # $self->{PERL_SRC} may be undefined
  345.     foreach $name (@snames){
  346.         if ($name !~ m![/:>\]]!) { push(@cand,$self->catfile($dir,$name)); }
  347.         else                     { push(@cand,$self->fixpath($name));      }
  348.     }
  349.     }
  350.     foreach $name (@cand) {
  351.     print "Checking $name\n" if ($trace >= 2);
  352.     next unless $vmsfile = $self->maybe_command($name);
  353.     $vmsfile =~ s/;[\d\-]*$//;  # Clip off version number; we can use a newer version as well
  354.     print "Executing $vmsfile\n" if ($trace >= 2);
  355.     if (`MCR $vmsfile -e "require $ver; print ""VER_OK\n"""` =~ /VER_OK/) {
  356.         print "Using PERL=MCR $vmsfile\n" if $trace;
  357.         return "MCR $vmsfile"
  358.     }
  359.     }
  360.     print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
  361.     0; # false and not empty
  362. }
  363.  
  364. =item path (override)
  365.  
  366. Translate logical name DCL$PATH as a searchlist, rather than trying
  367. to C<split> string value of C<$ENV{'PATH'}>.
  368.  
  369. =cut
  370.  
  371. sub path {
  372.     my(@dirs,$dir,$i);
  373.     while ($dir = $ENV{'DCL$PATH;' . $i++}) { push(@dirs,$dir); }
  374.     @dirs;
  375. }
  376.  
  377. =item maybe_command (override)
  378.  
  379. Follows VMS naming conventions for executable files.
  380. If the name passed in doesn't exactly match an executable file,
  381. appends F<.Exe> to check for executable image, and F<.Com> to check
  382. for DCL procedure.  If this fails, checks F<Sys$Share:> for an
  383. executable file having the name specified.  Finally, appends F<.Exe>
  384. and checks again.
  385.  
  386. =cut
  387.  
  388. sub maybe_command {
  389.     my($self,$file) = @_;
  390.     return $file if -x $file && ! -d _;
  391.     return "$file.exe" if -x "$file.exe";
  392.     return "$file.com" if -x "$file.com";
  393.     if ($file !~ m![/:>\]]!) {
  394.     my($shrfile) = 'Sys$Share:' . $file;
  395.     return $file if -x $shrfile && ! -d _;
  396.     return "$file.exe" if -x "$shrfile.exe";
  397.     }
  398.     return 0;
  399. }
  400.  
  401. =item maybe_command_in_dirs (override)
  402.  
  403. Uses DCL argument quoting on test command line.
  404.  
  405. =cut
  406.  
  407. sub maybe_command_in_dirs {    # $ver is optional argument if looking for perl
  408.     my($self, $names, $dirs, $trace, $ver) = @_;
  409.     my($name, $dir);
  410.     foreach $dir (@$dirs){
  411.     next unless defined $dir; # $self->{PERL_SRC} may be undefined
  412.     foreach $name (@$names){
  413.         my($abs,$tryabs);
  414.         if ($self->file_name_is_absolute($name)) {
  415.         $abs = $name;
  416.         } else {
  417.         $abs = $self->catfile($dir, $name);
  418.         }
  419.         print "Checking $abs for $name\n" if ($trace >= 2);
  420.         next unless $tryabs = $self->maybe_command($abs);
  421.         print "Substituting $tryabs instead of $abs\n" 
  422.         if ($trace >= 2 and $tryabs ne $abs);
  423.         $abs = $tryabs;
  424.         if (defined $ver) {
  425.         print "Executing $abs\n" if ($trace >= 2);
  426.         if (`$abs -e 'require $ver; print "VER_OK\n" ' 2>&1` =~ /VER_OK/) {
  427.             print "Using PERL=$abs\n" if $trace;
  428.             return $abs;
  429.         }
  430.         } else { # Do not look for perl
  431.         return $abs;
  432.         }
  433.     }
  434.     }
  435. }
  436.  
  437. =item perl_script (override)
  438.  
  439. If name passed in doesn't specify a readable file, appends F<.pl> and
  440. tries again, since it's customary to have file types on all files
  441. under VMS.
  442.  
  443. =cut
  444.  
  445. sub perl_script {
  446.     my($self,$file) = @_;
  447.     return $file if -r $file && ! -d _;
  448.     return "$file.pl" if -r "$file.pl" && ! -d _;
  449.     return '';
  450. }
  451.  
  452. =item file_name_is_absolute (override)
  453.  
  454. Checks for VMS directory spec as well as Unix separators.
  455.  
  456. =cut
  457.  
  458. sub file_name_is_absolute {
  459.     my($self,$file);
  460.     $file =~ m!^/! or $file =~ m![:<\[][^.\-]!;
  461. }
  462.  
  463. =item replace_manpage_separator
  464.  
  465. Use as separator a character which is legal in a VMS-syntax file name.
  466.  
  467. =cut
  468.  
  469. sub replace_manpage_separator {
  470.     my($self,$man) = @_;
  471.     $man = unixify($man);
  472.     $man =~ s#/+#__#g;
  473.     $man;
  474. }
  475.  
  476. =item init_others (override)
  477.  
  478. Provide VMS-specific forms of various utility commands, then hand
  479. off to the default MM_Unix method.
  480.  
  481. =cut
  482.  
  483. sub init_others {
  484.     my($self) = @_;
  485.  
  486.     $self->{NOOP} = "\t@ Continue";
  487.     $self->{FIRST_MAKEFILE} ||= 'Descrip.MMS';
  488.     $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS';
  489.     $self->{MAKEFILE} ||= $self->{FIRST_MAKEFILE};
  490.     $self->{NOECHO} ||= '@ ';
  491.     $self->{RM_F} = '$(PERL) -e "foreach (@ARGV) { 1 while ( -d $_ ? rmdir $_ : unlink $_)}"';
  492.     $self->{RM_RF} = '$(PERL) "-I$(PERL_LIB)" -e "use File::Path; @dirs = map(VMS::Filespec::unixify($_),@ARGV); rmtree(\@dirs,0,0)"';
  493.     $self->{TOUCH} = '$(PERL) -e "$t=time; foreach (@ARGV) { -e $_ ? utime($t,$t,@ARGV) : (open(F,qq(>$_)),close F)}"';
  494.     $self->{CHMOD} = '$(PERL) -e "chmod @ARGV"';  # expect Unix syntax from MakeMaker
  495.     $self->{CP} = 'Copy/NoConfirm';
  496.     $self->{MV} = 'Rename/NoConfirm';
  497.     $self->{UMASK_NULL} = "\t!";  
  498.     &ExtUtils::MM_Unix::init_others;
  499. }
  500.  
  501. =item constants (override)
  502.  
  503. Fixes up numerous file and directory macros to insure VMS syntax
  504. regardless of input syntax.  Also adds a few VMS-specific macros
  505. and makes lists of files comma-separated.
  506.  
  507. =cut
  508.  
  509. sub constants {
  510.     my($self) = @_;
  511.     my(@m,$def,$macro);
  512.  
  513.     if ($self->{DEFINE} ne '') {
  514.     my(@defs) = split(/\s+/,$self->{DEFINE});
  515.     foreach $def (@defs) {
  516.         next unless $def;
  517.         $def =~ s/^-D//;
  518.         $def = "\"$def\"" if $def =~ /=/;
  519.     }
  520.     $self->{DEFINE} = join ',',@defs;
  521.     }
  522.  
  523.     if ($self->{OBJECT} =~ /\s/) {
  524.     $self->{OBJECT} =~ s/(\\)?\n+\s+/ /g;
  525.     $self->{OBJECT} = map($self->fixpath($_),split(/,?\s+/,$self->{OBJECT}));
  526.     }
  527.     $self->{LDFROM} = join(' ',map($self->fixpath($_),split(/,?\s+/,$self->{LDFROM})));
  528.  
  529.     if ($self->{'INC'} && $self->{INC} !~ m!/Include=!i) {
  530.     my(@val) = ( '/Include=(' );
  531.     my(@includes) = split(/\s+/,$self->{INC});
  532.     my($plural);
  533.     foreach (@includes) {
  534.         s/^-I//;
  535.         push @val,', ' if $plural++;
  536.         push @val,$self->fixpath($_,1);
  537.     }
  538.     $self->{INC} = join('',@val,')');
  539.     }
  540.  
  541.     # Fix up directory specs
  542.     $self->{ROOTEXT} = $self->{ROOTEXT} ? $self->fixpath($self->{ROOTEXT},1)
  543.                                         : '[]';
  544.     foreach $macro ( qw [
  545.             INST_BIN INST_SCRIPT INST_LIB INST_ARCHLIB INST_EXE INSTALLPRIVLIB
  546.             INSTALLARCHLIB INSTALLSCRIPT INSTALLBIN PERL_LIB PERL_ARCHLIB
  547.             PERL_INC PERL_SRC FULLEXT INST_MAN1DIR INSTALLMAN1DIR
  548.             INST_MAN3DIR INSTALLMAN3DIR INSTALLSITELIB INSTALLSITEARCH
  549.             SITELIBEXP SITEARCHEXP ] ) {
  550.     next unless defined $self->{$macro};
  551.     $self->{$macro} = $self->fixpath($self->{$macro},1);
  552.     }
  553.     $self->{PERL_VMS} = $self->catdir($self->{PERL_SRC},q(VMS))
  554.     if ($self->{PERL_SRC});
  555.                         
  556.  
  557.  
  558.     # Fix up file specs
  559.     foreach $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKE_APERL_FILE MYEXTLIB] ) {
  560.     next unless defined $self->{$macro};
  561.     $self->{$macro} = $self->fixpath($self->{$macro});
  562.     }
  563.  
  564.     foreach $macro (qw/
  565.           AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION VERSION_SYM XS_VERSION
  566.           INST_BIN INST_EXE INST_LIB INST_ARCHLIB INST_SCRIPT PREFIX
  567.           INSTALLDIRS INSTALLPRIVLIB  INSTALLARCHLIB INSTALLSITELIB
  568.           INSTALLSITEARCH INSTALLBIN INSTALLSCRIPT PERL_LIB
  569.           PERL_ARCHLIB SITELIBEXP SITEARCHEXP LIBPERL_A MYEXTLIB
  570.           FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC PERL_VMS
  571.           PERL_INC PERL FULLPERL
  572.           / ) {
  573.     next unless defined $self->{$macro};
  574.     push @m, "$macro = $self->{$macro}\n";
  575.     }
  576.  
  577.  
  578.     push @m, q[
  579. VERSION_MACRO = VERSION
  580. DEFINE_VERSION = "$(VERSION_MACRO)=""$(VERSION)"""
  581. XS_VERSION_MACRO = XS_VERSION
  582. XS_DEFINE_VERSION = "$(XS_VERSION_MACRO)=""$(XS_VERSION)"""
  583.  
  584. MAKEMAKER = ],$self->catfile($self->{PERL_LIB},'ExtUtils','MakeMaker.pm'),qq[
  585. MM_VERSION = $ExtUtils::MakeMaker::VERSION
  586. MM_REVISION = $ExtUtils::MakeMaker::Revision
  587. MM_VMS_REVISION = $ExtUtils::MM_VMS::Revision
  588.  
  589. # FULLEXT = Pathname for extension directory (eg DBD/Oracle).
  590. # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT.
  591. # PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
  592. # DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
  593. ];
  594.  
  595.     for $tmp (qw/
  596.           FULLEXT BASEEXT PARENT_NAME DLBASE VERSION_FROM INC DEFINE OBJECT
  597.           LDFROM LINKTYPE
  598.           /    ) {
  599.     next unless defined $self->{$tmp};
  600.     push @m, "$tmp = $self->{$tmp}\n";
  601.     }
  602.  
  603.     for $tmp (qw/ XS MAN1PODS MAN3PODS PM /) {
  604.     next unless defined $self->{$tmp};
  605.     my(%tmp,$key);
  606.     for $key (keys %{$self->{$tmp}}) {
  607.         $tmp{$self->fixpath($key)} = $self->fixpath($self->{$tmp}{$key});
  608.     }
  609.     $self->{$tmp} = \%tmp;
  610.     }
  611.  
  612.     for $tmp (qw/ C O_FILES H /) {
  613.     next unless defined $self->{$tmp};
  614.     my(@tmp,$val);
  615.     for $val (@{$self->{$tmp}}) {
  616.         push(@tmp,$self->fixpath($val));
  617.     }
  618.     $self->{$tmp} = \@tmp;
  619.     }
  620.  
  621.     push @m,'
  622.  
  623. # Handy lists of source code files:
  624. XS_FILES = ',join(', ', sort keys %{$self->{XS}}),'
  625. C_FILES  = ',join(', ', @{$self->{C}}),'
  626. O_FILES  = ',join(', ', @{$self->{O_FILES}} ),'
  627. H_FILES  = ',join(', ', @{$self->{H}}),'
  628. MAN1PODS = ',join(', ', sort keys %{$self->{MAN1PODS}}),'
  629. MAN3PODS = ',join(', ', sort keys %{$self->{MAN3PODS}}),'
  630.  
  631. ';
  632.  
  633.     for $tmp (qw/
  634.           INST_MAN1DIR INSTALLMAN1DIR MAN1EXT INST_MAN3DIR INSTALLMAN3DIR MAN3EXT
  635.           /) {
  636.     next unless defined $self->{$tmp};
  637.     push @m, "$tmp = $self->{$tmp}\n";
  638.     }
  639.  
  640. push @m,"
  641. .SUFFIXES : \$(OBJ_EXT) .c .cpp .cxx .xs
  642.  
  643. # Here is the Config.pm that we are using/depend on
  644. CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h \$(VERSION_FROM)
  645.  
  646. # Where to put things:
  647. INST_LIBDIR = ",($self->{'INST_LIBDIR'} = $self->catdir($self->{INST_LIB},$self->{ROOTEXT})),"
  648. INST_ARCHLIBDIR = ",($self->{'INST_ARCHLIBDIR'} = $self->catdir($self->{INST_ARCHLIB},$self->{ROOTEXT})),"
  649.  
  650. INST_AUTODIR = ",($self->{'INST_AUTODIR'} = $self->catdir($self->{INST_LIB},'auto',$self->{FULLEXT})),'
  651. INST_ARCHAUTODIR = ',($self->{'INST_ARCHAUTODIR'} = $self->catdir($self->{INST_ARCHLIB},'auto',$self->{FULLEXT})),'
  652. ';
  653.  
  654.     if ($self->has_link_code()) {
  655.     push @m,'
  656. INST_STATIC = $(INST_ARCHAUTODIR)$(BASEEXT)$(LIB_EXT)
  657. INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT)
  658. INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs
  659. ';
  660.     } else {
  661.     push @m,'
  662. INST_STATIC =
  663. INST_DYNAMIC =
  664. INST_BOOT =
  665. EXPORT_LIST = $(BASEEXT).opt
  666. PERL_ARCHIVE = ',($ENV{'PERLSHR'} ? $ENV{'PERLSHR'} : 'Sys$Share:PerlShr.Exe'),'
  667. ';
  668.     }
  669.  
  670.     $self->{TO_INST_PM} = [ sort keys %{$self->{PM}} ];
  671.     $self->{PM_TO_BLIB} = [ %{$self->{PM}} ];
  672.     push @m,'
  673. TO_INST_PM = ',join(', ',@{$self->{TO_INST_PM}}),'
  674.  
  675. PM_TO_BLIB = ',join(', ',@{$self->{PM_TO_BLIB}}),'
  676. ';
  677.  
  678.     join('',@m);
  679. }
  680.  
  681. =item const_loadlibs (override)
  682.  
  683. Basically a stub which passes through library specfications provided
  684. by the caller.  Will be updated or removed when VMS support is added
  685. to ExtUtils::Liblist.
  686.  
  687. =cut
  688.  
  689. sub const_loadlibs{
  690.     my($self) = @_;
  691.     my (@m);
  692.     push @m, "
  693. # $self->{NAME} might depend on some other libraries.
  694. # (These comments may need revising:)
  695. #
  696. # Dependent libraries can be linked in one of three ways:
  697. #
  698. #  1.  (For static extensions) by the ld command when the perl binary
  699. #      is linked with the extension library. See EXTRALIBS below.
  700. #
  701. #  2.  (For dynamic extensions) by the ld command when the shared
  702. #      object is built/linked. See LDLOADLIBS below.
  703. #
  704. #  3.  (For dynamic extensions) by the DynaLoader when the shared
  705. #      object is loaded. See BSLOADLIBS below.
  706. #
  707. # EXTRALIBS =    List of libraries that need to be linked with when
  708. #        linking a perl binary which includes this extension
  709. #        Only those libraries that actually exist are included.
  710. #        These are written to a file and used when linking perl.
  711. #
  712. # LDLOADLIBS =    List of those libraries which can or must be linked into
  713. #        the shared library when created using ld. These may be
  714. #        static or dynamic libraries.
  715. #        LD_RUN_PATH is a colon separated list of the directories
  716. #        in LDLOADLIBS. It is passed as an environment variable to
  717. #        the process that links the shared library.
  718. #
  719. # BSLOADLIBS =    List of those libraries that are needed but can be
  720. #        linked in dynamically at run time on this platform.
  721. #        SunOS/Solaris does not need this because ld records
  722. #        the information (from LDLOADLIBS) into the object file.
  723. #        This list is used to create a .bs (bootstrap) file.
  724. #
  725. EXTRALIBS  = ",map($self->fixpath($_) . ' ',$self->{'EXTRALIBS'}),"
  726. BSLOADLIBS = ",map($self->fixpath($_) . ' ',$self->{'BSLOADLIBS'}),"
  727. LDLOADLIBS = ",map($self->fixpath($_) . ' ',$self->{'LDLOADLIBS'}),"\n";
  728.  
  729.     join('',@m);
  730. }
  731.  
  732. =item cflags (override)
  733.  
  734. Bypass shell script and produce qualifiers for CC directly (but warn
  735. user if a shell script for this extension exists).  Fold multiple
  736. /Defines into one, and do the same with /Includes, since some C
  737. compilers pay attention to only one instance of these qualifiers
  738. on the command line.
  739.  
  740. =cut
  741.  
  742. sub cflags {
  743.     my($self,$libperl) = @_;
  744.     my($quals) = $Config{'ccflags'};
  745.     my($name,$sys,@m);
  746.     my($optimize) = '/Optimize';
  747.  
  748.     ( $name = $self->{NAME} . "_cflags" ) =~ s/:/_/g ;
  749.     print STDOUT "Unix shell script ".$Config{"$self->{'BASEEXT'}_cflags"}.
  750.          " required to modify CC command for $self->{'BASEEXT'}\n"
  751.     if ($Config{$name});
  752.  
  753.     # Deal with $self->{DEFINE} here since some C compilers pay attention
  754.     # to only one /Define clause on command line, so we have to
  755.     # conflate the ones from $Config{'cc'} and $self->{DEFINE}
  756.     if ($quals =~ m:(.*)/define=\(?([^\(\/\)\s]+)\)?(.*)?:i) {
  757.     $quals = "$1/Define=($2," . ($self->{DEFINE} ? "$self->{DEFINE}," : '') .
  758.              "\$(DEFINE_VERSION),\$(XS_DEFINE_VERSION))$3";
  759.     }
  760.     else {
  761.     $quals .= '/Define=(' . ($self->{DEFINE} ? "$self->{DEFINE}," : '') .
  762.               '$(DEFINE_VERSION),$(XS_DEFINE_VERSION))';
  763.     }
  764.  
  765.     $libperl or $libperl = $self->{LIBPERL_A} || "libperl.olb";
  766.     if ($libperl =~ /libperl(\w+)\./i) {
  767.         my($type) = uc $1;
  768.         my(%map) = ( 'D'  => 'DEBUGGING', 'E' => 'EMBED', 'M' => 'MULTIPLICITY',
  769.                      'DE' => 'DEBUGGING,EMBED', 'DM' => 'DEBUGGING,MULTIPLICITY',
  770.                      'EM' => 'EMBED,MULTIPLICITY', 'DEM' => 'DEBUGGING,EMBED,MULTIPLICITY' );
  771.         $quals =~ s:/define=\(([^\)]+)\):/Define=($1,$map{$type}):i
  772.     }
  773.  
  774.     # Likewise with $self->{INC} and /Include
  775.     my($incstr) = '/Include=($(PERL_INC)';
  776.     if ($self->{'INC'}) {
  777.     my(@includes) = split(/\s+/,$self->{INC});
  778.     foreach (@includes) {
  779.         s/^-I//;
  780.         $incstr .= ', '.$self->fixpath($_,1);
  781.     }
  782.     }
  783.     if ($quals =~ m:(.*)/include=\(?([^\(\/\)\s]+)\)?(.*):i) {
  784.     $quals = "$1$incstr,$2)$3";
  785.     }
  786.     else { $quals .= "$incstr)"; }
  787.  
  788.     $optimize = '/Debug/NoOptimize'
  789.     if ($self->{OPTIMIZE} =~ /-g/ or $self->{OPTIMIZE} =~ m!/Debug!i);
  790.  
  791.     return $self->{CFLAGS} = qq{
  792. CCFLAGS = $quals
  793. OPTIMIZE = $optimize
  794. PERLTYPE =
  795. SPLIT =
  796. LARGE =
  797. };
  798. }
  799.  
  800. =item const_cccmd (override)
  801.  
  802. Adds directives to point C preprocessor to the right place when
  803. handling #include <sys/foo.h> directives.  Also constructs CC
  804. command line a bit differently than MM_Unix method.
  805.  
  806. =cut
  807.  
  808. sub const_cccmd {
  809.     my($self,$libperl) = @_;
  810.     my(@m);
  811.  
  812.     return $self->{CONST_CCCMD} if $self->{CONST_CCCMD};
  813.     return '' unless $self->needs_linking();
  814.     if ($Config{'vms_cc_type'} eq 'gcc') {
  815.         push @m,'
  816. .FIRST
  817.     ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS]';
  818.     }
  819.     elsif ($Config{'vms_cc_type'} eq 'vaxc') {
  820.         push @m,'
  821. .FIRST
  822.     ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS Sys$Library
  823.     ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include';
  824.     }
  825.     else {
  826.         push @m,'
  827. .FIRST
  828.     ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS ',
  829.         ($Config{'arch'} eq 'VMS_AXP' ? 'Sys$Library' : 'DECC$Library_Include'),'
  830.     ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include';
  831.     }
  832.  
  833.     push(@m, "\n\nCCCMD = $Config{'cc'} \$(CCFLAGS)\$(OPTIMIZE)\n");
  834.  
  835.     $self->{CONST_CCCMD} = join('',@m);
  836. }
  837.  
  838. =item pm_to_blib (override)
  839.  
  840. DCL I<still> accepts a maximum of 255 characters on a command
  841. line, so we write the (potentially) long list of file names
  842. to a temp file, then persuade Perl to read it instead of the
  843. command line to find args.
  844.  
  845. =cut
  846.  
  847. sub pm_to_blib {
  848.     my($self) = @_;
  849.     my($line,$from,$to,@m);
  850.     my($autodir) = $self->catdir('$(INST_LIB)','auto');
  851.     my(@files) = @{$self->{PM_TO_BLIB}};
  852.  
  853.     push @m, q{
  854. # As always, keep under DCL's 255-char limit
  855. pm_to_blib : $(TO_INST_PM)
  856.     },$self->{NOECHO},q{$(PERL) -e "print '},shift(@files),q{ },shift(@files),q{'" >.MM_tmp
  857. };
  858.  
  859.     $line = '';  # avoid uninitialized var warning
  860.     while ($from = shift(@files),$to = shift(@files)) {
  861.     $line .= " $from $to";
  862.     if (length($line) > 128) {
  863.         push(@m,"\t$self->{NOECHO}\$(PERL) -e \"print '$line'\" >>.MM_tmp\n");
  864.         $line = '';
  865.     }
  866.     }
  867.     push(@m,"\t$self->{NOECHO}\$(PERL) -e \"print '$line'\" >>.MM_tmp\n") if $line;
  868.  
  869.     push(@m,q[    $(PERL) "-I$(PERL_LIB)" "-MExtUtils::Install" -e "pm_to_blib({split(' ',<STDIN>)},'].$autodir.q[')" <.MM_tmp]);
  870.     push(@m,qq[
  871.     $self->{NOECHO}Delete/NoLog/NoConfirm .MM_tmp;
  872.     $self->{NOECHO}\$(TOUCH) pm_to_blib.ts
  873. ]);
  874.  
  875.     join('',@m);
  876. }
  877.  
  878. =item tool_autosplit (override)
  879.  
  880. Use VMS-style quoting on command line.
  881.  
  882. =cut
  883.  
  884. sub tool_autosplit{
  885.     my($self, %attribs) = @_;
  886.     my($asl) = "";
  887.     $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
  888.     q{
  889. # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
  890. AUTOSPLITFILE = $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;"
  891. };
  892. }
  893.  
  894. =item tool_sxubpp (override)
  895.  
  896. Use VMS-style quoting on xsubpp command line.
  897.  
  898. =cut
  899.  
  900. sub tool_xsubpp {
  901.     my($self) = @_;
  902.     return '' unless $self->needs_linking;
  903.     my($xsdir) = $self->catdir($self->{PERL_LIB},'ExtUtils');
  904.     # drop back to old location if xsubpp is not in new location yet
  905.     $xsdir = $self->catdir($self->{PERL_SRC},'ext') unless (-f $self->catfile($xsdir,'xsubpp'));
  906.     my(@tmdeps) = '$(XSUBPPDIR)typemap';
  907.     if( $self->{TYPEMAPS} ){
  908.     my $typemap;
  909.     foreach $typemap (@{$self->{TYPEMAPS}}){
  910.         if( ! -f  $typemap ){
  911.             warn "Typemap $typemap not found.\n";
  912.         }
  913.         else{
  914.             push(@tmdeps, $self->fixpath($typemap));
  915.         }
  916.     }
  917.     }
  918.     push(@tmdeps, "typemap") if -f "typemap";
  919.     my(@tmargs) = map("-typemap $_", @tmdeps);
  920.     if( exists $self->{XSOPT} ){
  921.     unshift( @tmargs, $self->{XSOPT} );
  922.     }
  923.  
  924.     my $xsubpp_version = $self->xsubpp_version($self->catfile($xsdir,'xsubpp'));
  925.  
  926.     # What are the correct thresholds for version 1 && 2 Paul?
  927.     if ( $xsubpp_version > 1.923 ){
  928.     $self->{XSPROTOARG} = '' unless defined $self->{XSPROTOARG};
  929.     } else {
  930.     if (defined $self->{XSPROTOARG} && $self->{XSPROTOARG} =~ /\-prototypes/) {
  931.         print STDOUT qq{Warning: This extension wants to pass the switch "-prototypes" to xsubpp.
  932.     Your version of xsubpp is $xsubpp_version and cannot handle this.
  933.     Please upgrade to a more recent version of xsubpp.
  934. };
  935.     } else {
  936.         $self->{XSPROTOARG} = "";
  937.     }
  938.     }
  939.  
  940.     "
  941. XSUBPPDIR = $xsdir
  942. XSUBPP = \$(PERL) \"-I\$(PERL_ARCHLIB)\" \"-I\$(PERL_LIB)\" \$(XSUBPPDIR)xsubpp
  943. XSPROTOARG = $self->{XSPROTOARG}
  944. XSUBPPDEPS = @tmdeps
  945. XSUBPPARGS = @tmargs
  946. ";
  947. }
  948.  
  949. =item xsubpp_version (override)
  950.  
  951. Test xsubpp exit status according to VMS rules ($sts & 1 ==> good)
  952. rather than Unix rules ($sts == 0 ==> good).
  953.  
  954. =cut
  955.  
  956. sub xsubpp_version
  957. {
  958.     my($self,$xsubpp) = @_;
  959.     my ($version) ;
  960.     return '' unless $self->needs_linking;
  961.  
  962.     # try to figure out the version number of the xsubpp on the system
  963.  
  964.     # first try the -v flag, introduced in 1.921 & 2.000a2
  965.  
  966.     my $command = "$self->{PERL} \"-I$self->{PERL_LIB}\" $xsubpp -v";
  967.     print "Running: $command\n" if $Verbose;
  968.     $version = `$command` ;
  969.     warn "Running '$command' exits with status " . $? unless ($? & 1);
  970.     chop $version ;
  971.  
  972.     return $1 if $version =~ /^xsubpp version (.*)/ ;
  973.  
  974.     # nope, then try something else
  975.  
  976.     my $counter = '000';
  977.     my ($file) = 'temp' ;
  978.     $counter++ while -e "$file$counter"; # don't overwrite anything
  979.     $file .= $counter;
  980.  
  981.     local(*F);
  982.     open(F, ">$file") or die "Cannot open file '$file': $!\n" ;
  983.     print F <<EOM ;
  984. MODULE = fred PACKAGE = fred
  985.  
  986. int
  987. fred(a)
  988.     int    a;
  989. EOM
  990.  
  991.     close F ;
  992.  
  993.     $command = "$self->{PERL} $xsubpp $file";
  994.     print "Running: $command\n" if $Verbose;
  995.     my $text = `$command` ;
  996.     warn "Running '$command' exits with status " . $? unless ($? & 1);
  997.     unlink $file ;
  998.  
  999.     # gets 1.2 -> 1.92 and 2.000a1
  1000.     return $1 if $text =~ /automatically by xsubpp version ([\S]+)\s*/  ;
  1001.  
  1002.     # it is either 1.0 or 1.1
  1003.     return 1.1 if $text =~ /^Warning: ignored semicolon/ ;
  1004.  
  1005.     # none of the above, so 1.0
  1006.     return "1.0" ;
  1007. }
  1008.  
  1009. =item tools_other (override)
  1010.  
  1011. Adds a few MM[SK] macros, and shortens some the installatin commands,
  1012. in order to stay under DCL's 255-character limit.  Also changes
  1013. EQUALIZE_TIMESTAMP to set revision date of target file to one second
  1014. later than source file, since MMK interprets precisely equal revision
  1015. dates for a source and target file as a sign that the target needs
  1016. to be updated.
  1017.  
  1018. =cut
  1019.  
  1020. sub tools_other {
  1021.     my($self) = @_;
  1022.     qq!
  1023. # Assumes \$(MMS) invokes MMS or MMK
  1024. # (It is assumed in some cases later that the default makefile name
  1025. # (Descrip.MMS for MM[SK]) is used.)
  1026. USEMAKEFILE = /Descrip=
  1027. USEMACROS = /Macro=(
  1028. MACROEND = )
  1029. MAKEFILE = Descrip.MMS
  1030. SHELL = Posix
  1031. TOUCH = $self->{TOUCH}
  1032. CHMOD = $self->{CHMOD}
  1033. CP = $self->{CP}
  1034. MV = $self->{MV}
  1035. RM_F  = $self->{RM_F}
  1036. RM_RF = $self->{RM_RF}
  1037. UMASK_NULL = $self->{UMASK_NULL}
  1038. NOOP = $self->{NOOP}
  1039. MKPATH = Create/Directory
  1040. EQUALIZE_TIMESTAMP = \$(PERL) -we "open F,qq{>\$ARGV[1]};close F;utime(0,(stat(\$ARGV[0]))[9]+1,\$ARGV[1])"
  1041. !. ($self->{PARENT} ? '' : 
  1042. qq!WARN_IF_OLD_PACKLIST = \$(PERL) -e "if (-f \$ARGV[0]){print qq[WARNING: Old package found (\$ARGV[0]); please check for collisions\\n]}"
  1043. MOD_INSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "install({split(' ',<STDIN>)},1);"
  1044. DOC_INSTALL = \$(PERL) -e "\@ARGV=split('|',<STDIN>);print '=head3 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];while(\$key=shift && \$val=shift){print qq[=item *\\n\\nC<\$key: \$val>\\n\\n];}print qq[=back\\n\\n]"
  1045. UNINSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "uninstall(\$ARGV[0],1);"
  1046. !);
  1047. }
  1048.  
  1049. =item dist (override)
  1050.  
  1051. Provide VMSish defaults for some values, then hand off to
  1052. default MM_Unix method.
  1053.  
  1054. =cut
  1055.  
  1056. sub dist {
  1057.     my($self, %attribs) = @_;
  1058.     $attribs{VERSION}      ||= $self->{VERSION_SYM};
  1059.     $attribs{ZIPFLAGS}     ||= '-Vu';
  1060.     $attribs{COMPRESS}     ||= 'gzip';
  1061.     $attribs{SUFFIX}       ||= '-gz';
  1062.     $attribs{SHAR}         ||= 'vms_share';
  1063.     $attribs{DIST_DEFAULT} ||= 'zipdist';
  1064.  
  1065.     return ExtUtils::MM_Unix::dist($self,%attribs);
  1066. }
  1067.  
  1068. =item c_o (override)
  1069.  
  1070. Use VMS syntax on command line.  In particular, $(DEFINE) and
  1071. $(PERL_INC) have been pulled into $(CCCMD).  Also use MM[SK] macros.
  1072.  
  1073. =cut
  1074.  
  1075. sub c_o {
  1076.     my($self) = @_;
  1077.     return '' unless $self->needs_linking();
  1078.     '
  1079. .c$(OBJ_EXT) :
  1080.     $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
  1081.  
  1082. .cpp$(OBJ_EXT) :
  1083.     $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cpp
  1084.  
  1085. .cxx$(OBJ_EXT) :
  1086.     $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cxx
  1087.  
  1088. ';
  1089. }
  1090.  
  1091. =item xs_c (override)
  1092.  
  1093. Use MM[SK] macros.
  1094.  
  1095. =cut
  1096.  
  1097. sub xs_c {
  1098.     my($self) = @_;
  1099.     return '' unless $self->needs_linking();
  1100.     '
  1101. .xs.c :
  1102.     $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET)
  1103. ';
  1104. }
  1105.  
  1106. =item xs_o (override)
  1107.  
  1108. Use MM[SK] macros, and VMS command line for C compiler.
  1109.  
  1110. =cut
  1111.  
  1112. sub xs_o {    # many makes are too dumb to use xs_c then c_o
  1113.     my($self) = @_;
  1114.     return '' unless $self->needs_linking();
  1115.     '
  1116. .xs$(OBJ_EXT) :
  1117.     $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c
  1118.     $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
  1119. ';
  1120. }
  1121.  
  1122. =item top_targets (override)
  1123.  
  1124. Use VMS quoting on command line for Version_check.
  1125.  
  1126. =cut
  1127.  
  1128. sub top_targets {
  1129.     my($self) = shift;
  1130.     my(@m);
  1131.     push @m, '
  1132. all :: pure_all manifypods
  1133.     $(NOOP)
  1134.  
  1135. pure_all :: config pm_to_blib subdirs linkext
  1136.     $(NOOP)
  1137.  
  1138. subdirs :: $(MYEXTLIB)
  1139.     $(NOOP)
  1140.  
  1141. config :: $(MAKEFILE) $(INST_LIBDIR).exists
  1142.     $(NOOP)
  1143.  
  1144. config :: $(INST_ARCHAUTODIR).exists
  1145.     $(NOOP)
  1146.  
  1147. config :: $(INST_AUTODIR).exists
  1148.     $(NOOP)
  1149. ';
  1150.  
  1151.     push @m, q{
  1152. config :: Version_check
  1153.     $(NOOP)
  1154.  
  1155. } unless $self->{PARENT} or ($self->{PERL_SRC} && $self->{INSTALLDIRS} eq "perl") or $self->{NO_VC};
  1156.  
  1157.  
  1158.     push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]);
  1159.     if (%{$self->{MAN1PODS}}) {
  1160.     push @m, q[
  1161. config :: $(INST_MAN1DIR).exists
  1162.     $(NOOP)
  1163. ];
  1164.     push @m, $self->dir_target(qw[$(INST_MAN1DIR)]);
  1165.     }
  1166.     if (%{$self->{MAN3PODS}}) {
  1167.     push @m, q[
  1168. config :: $(INST_MAN3DIR).exists
  1169.     $(NOOP)
  1170. ];
  1171.     push @m, $self->dir_target(qw[$(INST_MAN3DIR)]);
  1172.     }
  1173.  
  1174.     push @m, '
  1175. $(O_FILES) : $(H_FILES)
  1176. ' if @{$self->{O_FILES} || []} && @{$self->{H} || []};
  1177.  
  1178.     push @m, q{
  1179. help :
  1180.     perldoc ExtUtils::MakeMaker
  1181. };
  1182.  
  1183.     push @m, q{
  1184. Version_check :
  1185.     },$self->{NOECHO},q{$(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
  1186.     "-MExtUtils::MakeMaker=Version_check" -e "&Version_check('$(MM_VERSION)')"
  1187. };
  1188.  
  1189.     join('',@m);
  1190. }
  1191.  
  1192. =item dlsyms (override)
  1193.  
  1194. Create VMS linker options files specifying universal symbols for this
  1195. extension's shareable image, and listing other shareable images or 
  1196. libraries to which it should be linked.
  1197.  
  1198. =cut
  1199.  
  1200. sub dlsyms {
  1201.     my($self,%attribs) = @_;
  1202.  
  1203.     return '' unless $self->needs_linking();
  1204.  
  1205.     my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
  1206.     my($vars)  = $attribs{DL_VARS}  || $self->{DL_VARS}  || [];
  1207.     my($srcdir)= $attribs{PERL_SRC} || $self->{PERL_SRC} || '';
  1208.     my(@m);
  1209.  
  1210.     unless ($self->{SKIPHASH}{'dynamic'}) {
  1211.     push(@m,'
  1212. dynamic :: rtls.opt $(INST_ARCHAUTODIR)$(BASEEXT).opt
  1213.     $(NOOP)
  1214. ');
  1215.     if ($srcdir) {
  1216.        my($popt) = $self->catfile($srcdir,'perlshr.opt');
  1217.        my($lopt) = $self->catfile($srcdir,'crtl.opt');
  1218.        push(@m,"# Depend on $(BASEEXT).opt to insure we copy here *after* autogenerating (wrong) rtls.opt in Mksymlists
  1219. rtls.opt : $popt $lopt \$(BASEEXT).opt
  1220.     Copy/Log $popt Sys\$Disk:[]rtls.opt
  1221.     Append/Log $lopt Sys\$Disk:[]rtls.opt
  1222. ");
  1223.     }
  1224.     else {
  1225.         push(@m,'
  1226. # rtls.opt is built in the same step as $(BASEEXT).opt
  1227. rtls.opt : $(BASEEXT).opt
  1228.     $(TOUCH) $(MMS$TARGET)
  1229. ');
  1230.     }
  1231.     }
  1232.  
  1233.     push(@m,'
  1234. static :: $(INST_ARCHAUTODIR)$(BASEEXT).opt
  1235.     $(NOOP)
  1236. ') unless $self->{SKIPHASH}{'static'};
  1237.  
  1238.     push(@m,'
  1239. $(INST_ARCHAUTODIR)$(BASEEXT).opt : $(BASEEXT).opt
  1240.     $(CP) $(MMS$SOURCE) $(MMS$TARGET)
  1241.  
  1242. $(BASEEXT).opt : Makefile.PL
  1243.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Mksymlists;" -
  1244.     ',qq[-e "Mksymlists('NAME' => '$self->{NAME}', 'DL_FUNCS' => ],
  1245.     neatvalue($funcs),q[, 'DL_VARS' => ],neatvalue($vars),')"
  1246.     $(PERL) -e "print ""$(INST_STATIC)/Include=$(BASEEXT)\n$(INST_STATIC)/Library\n"";" >>$(MMS$TARGET)
  1247. ');
  1248.  
  1249.     join('',@m);
  1250. }
  1251.  
  1252. =item dynamic_lib (override)
  1253.  
  1254. Use VMS Link command.
  1255.  
  1256. =cut
  1257.  
  1258. sub dynamic_lib {
  1259.     my($self, %attribs) = @_;
  1260.     return '' unless $self->needs_linking(); #might be because of a subdir
  1261.  
  1262.     return '' unless $self->has_link_code();
  1263.  
  1264.     my($otherldflags) = $attribs{OTHERLDFLAGS} || "";
  1265.     my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
  1266.     my(@m);
  1267.     push @m,"
  1268.  
  1269. OTHERLDFLAGS = $otherldflags
  1270. INST_DYNAMIC_DEP = $inst_dynamic_dep
  1271.  
  1272. ";
  1273.     push @m, '
  1274. $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt rtls.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
  1275.     ',$self->{NOECHO},'$(MKPATH) $(INST_ARCHAUTODIR)
  1276.     Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,rtls.opt/Option,$(PERL_INC)perlshr_attr.opt/Option
  1277. ';
  1278.  
  1279.     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
  1280.     join('',@m);
  1281. }
  1282.  
  1283. =item dynamic_bs (override)
  1284.  
  1285. Use VMS-style quoting on Mkbootstrap command line.
  1286.  
  1287. =cut
  1288.  
  1289. sub dynamic_bs {
  1290.     my($self, %attribs) = @_;
  1291.     return '
  1292. BOOTSTRAP =
  1293. ' unless $self->has_link_code();
  1294.     '
  1295. BOOTSTRAP = '."$self->{BASEEXT}.bs".'
  1296.  
  1297. # As MakeMaker mkbootstrap might not write a file (if none is required)
  1298. # we use touch to prevent make continually trying to remake it.
  1299. # The DynaLoader only reads a non-empty file.
  1300. $(BOOTSTRAP) : $(MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR).exists
  1301.     '.$self->{NOECHO}.'Write Sys$Output "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))"
  1302.     '.$self->{NOECHO}.'$(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
  1303.     -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');"
  1304.     '.$self->{NOECHO}.' $(TOUCH) $(MMS$TARGET)
  1305.  
  1306. $(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR).exists
  1307.     '.$self->{NOECHO}.'$(RM_RF) $(INST_BOOT)
  1308.     - $(CP) $(BOOTSTRAP) $(INST_BOOT)
  1309. ';
  1310. }
  1311.  
  1312. =item static_lib (override)
  1313.  
  1314. Use VMS commands to manipulate object library.
  1315.  
  1316. =cut
  1317.  
  1318. sub static_lib {
  1319.     my($self) = @_;
  1320.     return '' unless $self->needs_linking();
  1321.  
  1322.     return '
  1323. $(INST_STATIC) :
  1324.     $(NOOP)
  1325. ' unless ($self->{OBJECT} or @{$self->{C} || []} or $self->{MYEXTLIB});
  1326.  
  1327.     my(@m);
  1328.     push @m,'
  1329. # Rely on suffix rule for update action
  1330. $(OBJECT) : $(INST_ARCHAUTODIR).exists
  1331.  
  1332. $(INST_STATIC) : $(OBJECT) $(MYEXTLIB)
  1333. ';
  1334.     # If this extension has it's own library (eg SDBM_File)
  1335.     # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
  1336.     push(@m, '    $(CP) $(MYEXTLIB) $(MMS$TARGET)',"\n") if $self->{MYEXTLIB};
  1337.  
  1338.     push(@m,'
  1339.     If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)
  1340.     Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)
  1341.     ',$self->{NOECHO},'$(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR)extralibs.ld\';print F qq[$(EXTRALIBS)\n];close F;"
  1342. ');
  1343.     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
  1344.     join('',@m);
  1345. }
  1346.  
  1347.  
  1348. # sub installpm_x { # called by installpm perl file
  1349. #     my($self, $dist, $inst, $splitlib) = @_;
  1350. #     if ($inst =~ m!#!) {
  1351. #     warn "Warning: MM[SK] would have problems processing this file: $inst, SKIPPED\n";
  1352. #     return '';
  1353. #     }
  1354. #     $inst = $self->fixpath($inst);
  1355. #     $dist = $self->fixpath($dist);
  1356. #     my($instdir) = $inst =~ /([^\)]+\))[^\)]*$/ ? $1 : dirname($inst);
  1357. #     my(@m);
  1358. #     push(@m, "
  1359. # $inst : $dist \$(MAKEFILE) ${instdir}.exists \$(INST_ARCHAUTODIR).exists
  1360. # ",'    ',$self->{NOECHO},'$(RM_F) $(MMS$TARGET)
  1361. #     ',$self->{NOECHO},'$(CP) ',"$dist $inst",'
  1362. #     $(CHMOD) 644 $(MMS$TARGET)
  1363. # ');
  1364. #     push(@m, '    $(AUTOSPLITFILE) $(MMS$TARGET) ',
  1365. #               $self->catdir($splitlib,'auto')."\n\n")
  1366. #         if ($splitlib and $inst =~ /\.pm$/);
  1367. #     push(@m,$self->dir_target($instdir));
  1368. #     join('',@m);
  1369. # }
  1370.  
  1371. =item manifypods (override)
  1372.  
  1373. Use VMS-style quoting on command line, and VMS logical name
  1374. to specify fallback location at build time if we can't find pod2man.
  1375.  
  1376. =cut
  1377.  
  1378.  
  1379. sub manifypods {
  1380.     my($self, %attribs) = @_;
  1381.     return "\nmanifypods :\n\t\$(NOOP)\n" unless %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}};
  1382.     my($dist);
  1383.     my($pod2man_exe);
  1384.     if (defined $self->{PERL_SRC}) {
  1385.     $pod2man_exe = $self->catfile($self->{PERL_SRC},'pod','pod2man');
  1386.     } else {
  1387.     $pod2man_exe = $self->catfile($Config{scriptdirexp},'pod2man');
  1388.     }
  1389.     if ($pod2man_exe = $self->perl_script($pod2man_exe)) { $found_pod2man = 1; }
  1390.     else {
  1391.     # No pod2man but some MAN3PODS to be installed
  1392.     print <<END;
  1393.  
  1394. Warning: I could not locate your pod2man program.  As a last choice,
  1395.          I will look for the file to which the logical name POD2MAN
  1396.          points when MMK is invoked.
  1397.  
  1398. END
  1399.         $pod2man_exe = "pod2man";
  1400.     }
  1401.     my(@m);
  1402.     push @m,
  1403. qq[POD2MAN_EXE = $pod2man_exe\n],
  1404. q[POD2MAN = $(PERL) -we "%m=@ARGV;for (keys %m){" -
  1405. -e "system(""MCR $^X $(POD2MAN_EXE) $_ >$m{$_}"");}"
  1406. ];
  1407.     push @m, "\nmanifypods : ";
  1408.     push @m, join " ", keys %{$self->{MAN1PODS}}, keys %{$self->{MAN3PODS}};
  1409.     push(@m,"\n");
  1410.     if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) {
  1411.     my($pod);
  1412.     foreach $pod (sort keys %{$self->{MAN1PODS}}) {
  1413.         push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
  1414.         push @m, "$pod $self->{MAN1PODS}{$pod}\n";
  1415.     }
  1416.     foreach $pod (sort keys %{$self->{MAN3PODS}}) {
  1417.         push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
  1418.         push @m, "$pod $self->{MAN3PODS}{$pod}\n";
  1419.     }
  1420.     }
  1421.     join('', @m);
  1422. }
  1423.  
  1424. =item processPL (override)
  1425.  
  1426. Use VMS-style quoting on command line.
  1427.  
  1428. =cut
  1429.  
  1430. sub processPL {
  1431.     my($self) = @_;
  1432.     return "" unless $self->{PL_FILES};
  1433.     my(@m, $plfile);
  1434.     foreach $plfile (sort keys %{$self->{PL_FILES}}) {
  1435.     push @m, "
  1436. all :: $self->{PL_FILES}->{$plfile}
  1437.     \$(NOOP)
  1438.  
  1439. $self->{PL_FILES}->{$plfile} :: $plfile
  1440. ",'    $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '," $plfile
  1441. ";
  1442.     }
  1443.     join "", @m;
  1444. }
  1445.  
  1446. =item installbin (override)
  1447.  
  1448. Stay under DCL's 255 character command line limit once again by
  1449. splitting potentially long list of files across multiple lines
  1450. in C<realclean> target.
  1451.  
  1452. =cut
  1453.  
  1454. sub installbin {
  1455.     my($self) = @_;
  1456.     return '' unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY";
  1457.     return '' unless @{$self->{EXE_FILES}};
  1458.     my(@m, $from, $to, %fromto, @to, $line);
  1459.     for $from (@{$self->{EXE_FILES}}) {
  1460.     my($path) = '$(INST_SCRIPT)' . basename($from);
  1461.     local($_) = $path;  # backward compatibility
  1462.     $to = $self->libscan($path);
  1463.     print "libscan($from) => '$to'\n" if ($Verbose >=2);
  1464.     $fromto{$from}=$to;
  1465.     }
  1466.     @to   = values %fromto;
  1467.     push @m, "
  1468. EXE_FILES = @{$self->{EXE_FILES}}
  1469.  
  1470. all :: @to
  1471.     \$(NOOP)
  1472.  
  1473. realclean ::
  1474. ";
  1475.     $line = '';  #avoid unitialized var warning
  1476.     foreach $to (@to) {
  1477.     if (length($line) + length($to) > 80) {
  1478.         push @m, "\t\$(RM_F) $line\n";
  1479.         $line = $to;
  1480.     }
  1481.     else { $line .= " $to"; }
  1482.     }
  1483.     push @m, "\t\$(RM_F) $line\n\n" if $line;
  1484.  
  1485.     while (($from,$to) = each %fromto) {
  1486.     last unless defined $from;
  1487.     my $todir;
  1488.     if ($to =~ m#[/>:\]]#) { $todir = dirname($to); }
  1489.     else                   { ($todir = $to) =~ s/[^\)]+$//; }
  1490.     $todir = $self->fixpath($todir,1);
  1491.     push @m, "
  1492. $to : $from \$(MAKEFILE) ${todir}.exists
  1493.     \$(CP) $from $to
  1494.  
  1495. ", $self->dir_target($todir);
  1496.     }
  1497.     join "", @m;
  1498. }
  1499.  
  1500. =item subdir_x (override)
  1501.  
  1502. Use VMS commands to change default directory.
  1503.  
  1504. =cut
  1505.  
  1506. sub subdir_x {
  1507.     my($self, $subdir) = @_;
  1508.     my(@m,$key);
  1509.     $subdir = $self->fixpath($subdir,1);
  1510.     push @m, '
  1511.  
  1512. subdirs ::
  1513.     olddef = F$Environment("Default")
  1514.     Set Default ',$subdir,'
  1515.     - $(MMS) all $(USEMACROS)$(PASTHRU)$(MACROEND)
  1516.     Set Default \'olddef\'
  1517. ';
  1518.     join('',@m);
  1519. }
  1520.  
  1521. =item clean (override)
  1522.  
  1523. Split potentially long list of files across multiple commands (in
  1524. order to stay under the magic command line limit).  Also use MM[SK]
  1525. commands for handling subdirectories.
  1526.  
  1527. =cut
  1528.  
  1529. sub clean {
  1530.     my($self, %attribs) = @_;
  1531.     my(@m,$dir);
  1532.     push @m, '
  1533. # Delete temporary files but do not touch installed files. We don\'t delete
  1534. # the Descrip.MMS here so that a later make realclean still has it to use.
  1535. clean ::
  1536. ';
  1537.     foreach $dir (@{$self->{DIR}}) { # clean subdirectories first
  1538.     my($vmsdir) = $self->fixpath($dir,1);
  1539.     push( @m, '    If F$Search("'.$vmsdir.'$(MAKEFILE)") Then \\',"\n\t",
  1540.           '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) clean`;"',"\n");
  1541.     }
  1542.     push @m, '    $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso
  1543. ';
  1544.  
  1545.     my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files
  1546.     push(@otherfiles, $attribs{FILES}) if $attribs{FILES};
  1547.     push(@otherfiles, qw[ blib $(MAKE_APERL_FILE) extralibs.ld perlmain.c pm_to_blib.ts ]);
  1548.     push(@otherfiles,$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'));
  1549.     my($file,$line);
  1550.     $line = '';  #avoid unitialized var warning
  1551.     foreach $file (@otherfiles) {
  1552.     $file = $self->fixpath($file);
  1553.     if (length($line) + length($file) > 80) {
  1554.         push @m, "\t\$(RM_RF) $line\n";
  1555.         $line = "$file";
  1556.     }
  1557.     else { $line .= " $file"; }
  1558.     }
  1559.     push @m, "\t\$(RM_RF) $line\n" if line;
  1560.     push(@m, "    $attribs{POSTOP}\n") if $attribs{POSTOP};
  1561.     join('', @m);
  1562. }
  1563.  
  1564. =item realclean (override)
  1565.  
  1566. Guess what we're working around?  Also, use MM[SK] for subdirectories.
  1567.  
  1568. =cut
  1569.  
  1570. sub realclean {
  1571.     my($self, %attribs) = @_;
  1572.     my(@m);
  1573.     push(@m,'
  1574. # Delete temporary files (via clean) and also delete installed files
  1575. realclean :: clean
  1576. ');
  1577.     foreach(@{$self->{DIR}}){
  1578.     my($vmsdir) = $self->fixpath($_,1);
  1579.     push(@m, '    If F$Search("'."$vmsdir".'$(MAKEFILE)").nes."" Then \\',"\n\t",
  1580.           '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) realclean`;"',"\n");
  1581.     }
  1582.     push @m,'    $(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR)
  1583. ';
  1584.     # We can't expand several of the MMS macros here, since they don't have
  1585.     # corresponding %$self keys (i.e. they're defined in Descrip.MMS as a
  1586.     # combination of macros).  In order to stay below DCL's 255 char limit,
  1587.     # we put only 2 on a line.
  1588.     my($file,$line,$fcnt);
  1589.     my(@files) = qw{ $(MAKEFILE) $(MAKEFILE)_old };
  1590.     if ($self->has_link_code) {
  1591.     push(@files,qw{ $(INST_DYNAMIC) $(INST_STATIC) $(INST_BOOT) $(OBJECT) });
  1592.     }
  1593.     push(@files, values %{$self->{PM}});
  1594.     $line = '';  #avoid unitialized var warning
  1595.     foreach $file (@files) {
  1596.     $file = $self->fixpath($file);
  1597.     if (length($line) + length($file) > 80 || ++$fcnt >= 2) {
  1598.         push @m, "\t\$(RM_F) $line\n";
  1599.         $line = "$file";
  1600.         $fcnt = 0;
  1601.     }
  1602.     else { $line .= " $file"; }
  1603.     }
  1604.     push @m, "\t\$(RM_F) $line\n" if $line;
  1605.     if ($attribs{FILES} && ref $attribs{FILES} eq 'ARRAY') {
  1606.     $line = '';
  1607.     foreach $file (@{$attribs{'FILES'}}) {
  1608.         $file = $self->fixpath($file);
  1609.         if (length($line) + length($file) > 80) {
  1610.         push @m, "\t\$(RM_RF) $line\n";
  1611.         $line = "$file";
  1612.         }
  1613.         else { $line .= " $file"; }
  1614.     }
  1615.     push @m, "\t\$(RM_RF) $line\n" if $line;
  1616.     }
  1617.     push(@m, "    $attribs{POSTOP}\n")                     if $attribs{POSTOP};
  1618.     join('', @m);
  1619. }
  1620.  
  1621. =item dist_basics (override)
  1622.  
  1623. Use VMS-style quoting on command line.
  1624.  
  1625. =cut
  1626.  
  1627. sub dist_basics {
  1628.     my($self) = @_;
  1629. '
  1630. distclean :: realclean distcheck
  1631.     $(NOOP)
  1632.  
  1633. distcheck :
  1634.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; fullcheck()"
  1635.  
  1636. skipcheck :
  1637.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; skipcheck()"
  1638.  
  1639. manifest :
  1640.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&mkmanifest\'; mkmanifest()"
  1641. ';
  1642. }
  1643.  
  1644. =item dist_core (override)
  1645.  
  1646. Syntax for invoking F<VMS_Share> differs from that for Unix F<shar>,
  1647. so C<shdist> target actions are VMS-specific.
  1648.  
  1649. =cut
  1650.  
  1651. sub dist_core {
  1652.     my($self) = @_;
  1653. q[
  1654. dist : $(DIST_DEFAULT)
  1655.     ].$self->{NOECHO}.q[$(PERL) -le "print 'Warning: $m older than $vf' if -e ($vf = '$(VERSION_FROM)') && -M $vf < -M ($m = '$(MAKEFILE)'"
  1656.  
  1657. zipdist : $(DISTVNAME).zip
  1658.     $(NOOP)
  1659.  
  1660. $(DISTVNAME).zip : distdir
  1661.     $(PREOP)
  1662.     $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) $(SRC)
  1663.     $(RM_RF) $(DISTVNAME)
  1664.     $(POSTOP)
  1665.  
  1666. $(DISTVNAME).tar$(SUFFIX) : distdir
  1667.     $(PREOP)
  1668.     $(TO_UNIX)
  1669.     $(TAR) "$(TARFLAGS)" $(DISTVNAME).tar $(SRC)
  1670.     $(RM_RF) $(DISTVNAME)
  1671.     $(COMPRESS) $(DISTVNAME).tar
  1672.     $(POSTOP)
  1673.  
  1674. shdist : distdir
  1675.     $(PREOP)
  1676.     $(SHARE) $(SRC) $(DISTVNAME).share
  1677.     $(RM_RF) $(DISTVNAME)
  1678.     $(POSTOP)
  1679. ];
  1680. }
  1681.  
  1682. =item dist_dir (override)
  1683.  
  1684. Use VMS-style quoting on command line.
  1685.  
  1686. =cut
  1687.  
  1688. sub dist_dir {
  1689.     my($self) = @_;
  1690. q{
  1691. distdir :
  1692.     $(RM_RF) $(DISTVNAME)
  1693.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest '/mani/';" \\
  1694.     -e "manicopy(maniread(),'$(DISTVNAME)','$(DIST_CP)');"
  1695. };
  1696. }
  1697.  
  1698. =item dist_test (override)
  1699.  
  1700. Use VMS commands to change default directory, and use VMS-style
  1701. quoting on command line.
  1702.  
  1703. =cut
  1704.  
  1705. sub dist_test {
  1706.     my($self) = @_;
  1707. q{
  1708. disttest : distdir
  1709.     startdir = F$Environment("Default")
  1710.     Set Default [.$(DISTVNAME)]
  1711.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL
  1712.     $(MMS)
  1713.     $(MMS) test
  1714.     Set Default 'startdir'
  1715. };
  1716. }
  1717.  
  1718. # --- Test and Installation Sections ---
  1719.  
  1720. =item install (override)
  1721.  
  1722. Work around DCL's 255 character limit several times,and use
  1723. VMS-style command line quoting in a few cases.
  1724.  
  1725. =cut
  1726.  
  1727. sub install {
  1728.     my($self, %attribs) = @_;
  1729.     my(@m,@docfiles);
  1730.  
  1731.     if ($self->{EXE_FILES}) {
  1732.     my($line,$file) = ('','');
  1733.     foreach $file (@{$self->{EXE_FILES}}) {
  1734.         $line .= "$file ";
  1735.         if (length($line) > 128) {
  1736.         push(@docfiles,qq[\t\$(PERL) -e "print $line" >>.MM_tmp\n]);
  1737.         $line = '';
  1738.         }
  1739.     }
  1740.     push(@docfiles,qq[\t\$(PERL) -e "print $line" >>.MM_tmp\n]) if $line;
  1741.     }
  1742.  
  1743.     push @m, q[
  1744. install :: all pure_install doc_install
  1745.     $(NOOP)
  1746.  
  1747. install_perl :: all pure_perl_install doc_perl_install
  1748.     $(NOOP)
  1749.  
  1750. install_site :: all pure_site_install doc_site_install
  1751.     $(NOOP)
  1752.  
  1753. install_ :: install_site
  1754.     ],$self->{NOECHO},q[Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
  1755.  
  1756. pure_install :: pure_$(INSTALLDIRS)_install
  1757.     $(NOOP)
  1758.  
  1759. doc_install :: doc_$(INSTALLDIRS)_install
  1760.     ],$self->{NOECHO},q[Write Sys$Output "Appending installation info to $(INST_ARCHLIB)perllocal.pod"
  1761.  
  1762. pure__install : pure_site_install
  1763.     ],$self->{NOECHO},q[Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
  1764.  
  1765. doc__install : doc_site_install
  1766.     ],$self->{NOECHO},q[Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
  1767.  
  1768. # This hack brought to you by DCL's 255-character command line limit
  1769. pure_perl_install ::
  1770.     ].$self->{NOECHO}.q[$(PERL) -e "print 'read ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
  1771.     ].$self->{NOECHO}.q[$(PERL) -e "print 'write ].$self->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
  1772.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_LIB) $(INSTALLPRIVLIB) '" >>.MM_tmp
  1773.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLARCHLIB) '" >>.MM_tmp
  1774.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
  1775.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
  1776.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
  1777.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
  1778.     $(MOD_INSTALL) <.MM_tmp
  1779.     ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp;
  1780.     ].$self->{NOECHO}.q[$(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[
  1781.  
  1782. # Likewise
  1783. pure_site_install ::
  1784.     ].$self->{NOECHO}.q[$(PERL) -e "print 'read ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
  1785.     ].$self->{NOECHO}.q[$(PERL) -e "print 'write ].$self->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
  1786.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_LIB) $(INSTALLSITELIB) '" >>.MM_tmp
  1787.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLSITEARCH) '" >>.MM_tmp
  1788.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
  1789.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
  1790.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
  1791.     ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
  1792.     $(MOD_INSTALL) <.MM_tmp
  1793.     ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp;
  1794.     ].$self->{NOECHO}.q[$(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
  1795.  
  1796. # Ditto
  1797. doc_perl_install ::
  1798.     ].$self->{NOECHO}.q[$(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLPRIVLIB)|'" >.MM_tmp
  1799.     ].$self->{NOECHO}.q[$(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp
  1800.     ].$self->{NOECHO}.q[$(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp
  1801. ],@docfiles,q[    $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
  1802.     ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp;
  1803.  
  1804. # And again
  1805. doc_site_install ::
  1806.     ].$self->{NOECHO}.q[$(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLSITELIB)|'" >.MM_tmp
  1807.     ].$self->{NOECHO}.q[$(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp
  1808.     ].$self->{NOECHO}.q[$(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp
  1809. ],@docfiles,q[    $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
  1810.     ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp;
  1811.  
  1812. ];
  1813.  
  1814.     push @m, q[
  1815. uninstall :: uninstall_from_$(INSTALLDIRS)dirs
  1816.     $(NOOP)
  1817.  
  1818. uninstall_from_perldirs ::
  1819.     ].$self->{NOECHO}.q[$(UNINSTALL) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
  1820.  
  1821. uninstall_from_sitedirs ::
  1822.     ].$self->{NOECHO}.q[$(UNINSTALL) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist')."\n";
  1823.  
  1824.     join('',@m);
  1825. }
  1826.  
  1827. =item perldepend (override)
  1828.  
  1829. Use VMS-style syntax for files; it's cheaper to just do it directly here
  1830. than to have the MM_Unix method call C<catfile> repeatedly.  Also use
  1831. config.vms as source of original config data if the Perl distribution
  1832. is available; config.sh is an ancillary file under VMS.  Finally, if
  1833. we have to rebuild Config.pm, use MM[SK] to do it.
  1834.  
  1835. =cut
  1836.  
  1837. sub perldepend {
  1838.     my($self) = @_;
  1839.     my(@m);
  1840.  
  1841.     push @m, '
  1842. $(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h, $(PERL_INC)av.h
  1843. $(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h, $(PERL_INC)form.h
  1844. $(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h, $(PERL_INC)keywords.h
  1845. $(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)op.h, $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h
  1846. $(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)proto.h
  1847. $(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h
  1848. $(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h
  1849.  
  1850. ' if $self->{OBJECT}; 
  1851.  
  1852.     if ($self->{PERL_SRC}) {
  1853.     my(@macros);
  1854.     my($mmsquals) = '$(USEMAKEFILE)[.vms]$(MAKEFILE)';
  1855.     push(@macros,'__AXP__=1') if $Config{'arch'} eq 'VMS_AXP';
  1856.     push(@macros,'DECC=1')    if $Config{'vms_cc_type'} eq 'decc';
  1857.     push(@macros,'GNUC=1')    if $Config{'vms_cc_type'} eq 'gcc';
  1858.     push(@macros,'SOCKET=1')  if $Config{'d_has_sockets'};
  1859.     push(@macros,qq["CC=$Config{'cc'}"])  if $Config{'cc'} =~ m!/!;
  1860.     $mmsquals .= '$(USEMACROS)' . join(',',@macros) . '$(MACROEND)' if @macros;
  1861.     push(@m,q[
  1862. # Check for unpropagated config.sh changes. Should never happen.
  1863. # We do NOT just update config.h because that is not sufficient.
  1864. # An out of date config.h is not fatal but complains loudly!
  1865. #$(PERL_INC)config.h : $(PERL_SRC)config.sh
  1866. $(PERL_INC)config.h : $(PERL_VMS)config.vms
  1867.     ],$self->{NOECHO},q[Write Sys$Error "Warning: $(PERL_INC)config.h out of date with $(PERL_VMS)config.vms"
  1868.  
  1869. #$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh
  1870. $(PERL_ARCHLIB)Config.pm : $(PERL_VMS)config.vms $(PERL_VMS)genconfig.pl
  1871.     ],$self->{NOECHO},q[Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.vms or genconfig.pl"
  1872.     olddef = F$Environment("Default")
  1873.     Set Default $(PERL_SRC)
  1874.     $(MMS)],$mmsquals,q[ $(MMS$TARGET)
  1875.     Set Default 'olddef'
  1876. ]);
  1877.     }
  1878.  
  1879.     push(@m, join(" ", map($self->fixpath($_),values %{$self->{XS}}))." : \$(XSUBPPDEPS)\n")
  1880.       if %{$self->{XS}};
  1881.  
  1882.     join('',@m);
  1883. }
  1884.  
  1885. =item makefile (override)
  1886.  
  1887. Use VMS commands and quoting.
  1888.  
  1889. =cut
  1890.  
  1891. sub makefile {
  1892.     my($self) = @_;
  1893.     my(@m,@cmd);
  1894.     # We do not know what target was originally specified so we
  1895.     # must force a manual rerun to be sure. But as it should only
  1896.     # happen very rarely it is not a significant problem.
  1897.     push @m, q[
  1898. $(OBJECT) : $(FIRST_MAKEFILE)
  1899. ] if $self->{OBJECT};
  1900.  
  1901.     push @m,q[
  1902. # We take a very conservative approach here, but it\'s worth it.
  1903. # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping.
  1904. $(MAKEFILE) : Makefile.PL $(CONFIGDEP)
  1905.     ],$self->{NOECHO},q[Write Sys$Output "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)"
  1906.     ],$self->{NOECHO},q[Write Sys$Output "Cleaning current config before rebuilding $(MAKEFILE) ..."
  1907.     - $(MV) $(MAKEFILE) $(MAKEFILE)_old
  1908.     - $(MMS) $(USEMAKEFILE)$(MAKEFILE)_old clean
  1909.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[
  1910.     ],$self->{NOECHO},q[Write Sys$Output "$(MAKEFILE) has been rebuilt."
  1911.     ],$self->{NOECHO},q[Write Sys$Output "Please run $(MMS) to build the extension."
  1912. ];
  1913.  
  1914.     join('',@m);
  1915. }
  1916.  
  1917. =item test (override)
  1918.  
  1919. Use VMS commands for handling subdirectories.
  1920.  
  1921. =cut
  1922.  
  1923. sub test {
  1924.     my($self, %attribs) = @_;
  1925.     my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : '');
  1926.     my(@m);
  1927.     push @m,"
  1928. TEST_VERBOSE = 0
  1929. TEST_TYPE = test_\$(LINKTYPE)
  1930. TEST_FILE = test.pl
  1931. TESTDB_SW = -d
  1932.  
  1933. test :: \$(TEST_TYPE)
  1934.     \$(NOOP)
  1935.  
  1936. testdb :: testdb_\$(LINKTYPE)
  1937.     \$(NOOP)
  1938.  
  1939. ";
  1940.     foreach(@{$self->{DIR}}){
  1941.       my($vmsdir) = $self->fixpath($_,1);
  1942.       push(@m, '    If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'",
  1943.            '; print `$(MMS) $(PASTHRU2) test`'."\n");
  1944.     }
  1945.     push(@m, "\t$self->{NOECHO}Write Sys\$Output \"No tests defined for \$(NAME) extension.\"\n")
  1946.         unless $tests or -f "test.pl" or @{$self->{DIR}};
  1947.     push(@m, "\n");
  1948.  
  1949.     push(@m, "test_dynamic :: pure_all\n");
  1950.     push(@m, $self->test_via_harness('$(FULLPERL)', $tests)) if $tests;
  1951.     push(@m, $self->test_via_script('$(FULLPERL)', 'test.pl')) if -f "test.pl";
  1952.     push(@m, "    \$(NOOP)\n") if (!$tests && ! -f "test.pl");
  1953.     push(@m, "\n");
  1954.  
  1955.     push(@m, "testdb_dynamic :: pure_all\n");
  1956.     push(@m, $self->test_via_script('$(FULLPERL) "$(TESTDB_SW)"', '$(TEST_FILE)'));
  1957.     push(@m, "\n");
  1958.  
  1959.     # Occasionally we may face this degenerate target:
  1960.     push @m, "test_ : test_dynamic\n\n";
  1961.  
  1962.     if ($self->needs_linking()) {
  1963.     push(@m, "test_static :: pure_all \$(MAP_TARGET)\n");
  1964.     push(@m, $self->test_via_harness('$(MAP_TARGET)', $tests)) if $tests;
  1965.     push(@m, $self->test_via_script('$(MAP_TARGET)', 'test.pl')) if -f 'test.pl';
  1966.     push(@m, "\n");
  1967.     push(@m, "testdb_static :: pure_all \$(MAP_TARGET)\n");
  1968.     push(@m, $self->test_via_script('$(MAP_TARGET) $(TESTDB_SW)', '$(TEST_FILE)'));
  1969.     push(@m, "\n");
  1970.     }
  1971.     else {
  1972.     push @m, "test_static :: test_dynamic\n\t$self->{NOECHO}\$(NOOP)\n\n";
  1973.     push @m, "testdb_static :: testdb_dynamic\n\t$self->{NOECHO}\$(NOOP)\n";
  1974.     }
  1975.  
  1976.     join('',@m);
  1977. }
  1978.  
  1979. =item test_via_harness (override)
  1980.  
  1981. Use VMS-style quoting on command line.
  1982.  
  1983. =cut
  1984.  
  1985. sub test_via_harness {
  1986.     my($self,$perl,$tests) = @_;
  1987.     "    $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" \\'."\n\t".
  1988.     '-e "use Test::Harness qw(&runtests $verbose); $verbose=$(TEST_VERBOSE); runtests @ARGV;" \\'."\n\t$tests\n";
  1989. }
  1990.  
  1991. =item test_via_script (override)
  1992.  
  1993. Use VMS-style quoting on command line.
  1994.  
  1995. =cut
  1996.  
  1997. sub test_via_script {
  1998.     my($self,$perl,$script) = @_;
  1999.     "    $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '.$script.'
  2000. ';
  2001. }
  2002.  
  2003. =item makeaperl (override)
  2004.  
  2005. Undertake to build a new set of Perl images using VMS commands.  Since
  2006. VMS does dynamic loading, it's not necessary to statically link each
  2007. extension into the Perl image, so this isn't the normal build path.
  2008. Consequently, it hasn't really been tested, and may well be incomplete.
  2009.  
  2010. =cut
  2011.  
  2012. sub makeaperl {
  2013.     my($self, %attribs) = @_;
  2014.     my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmp, $libperl) = 
  2015.       @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
  2016.     my(@m);
  2017.     push @m, "
  2018. # --- MakeMaker makeaperl section ---
  2019. MAP_TARGET    = $target
  2020. ";
  2021.     return join '', @m if $self->{PARENT};
  2022.  
  2023.     my($dir) = join ":", @{$self->{DIR}};
  2024.  
  2025.     unless ($self->{MAKEAPERL}) {
  2026.     push @m, q{
  2027. $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
  2028.     },$self->{NOECHO},q{Write Sys$Output "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)"
  2029.     },$self->{NOECHO},q{$(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" \
  2030.         Makefile.PL DIR=}, $dir, q{ \
  2031.         MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
  2032.         MAKEAPERL=1 NORECURS=1
  2033.  
  2034. $(MAP_TARGET) :: $(MAKE_APERL_FILE)
  2035.     $(MMS)$(USEMAKEFILE)$(MAKE_APERL_FILE) static $(MMS$TARGET)
  2036. };
  2037.     push @m, map( " \\\n\t\t$_", @ARGV );
  2038.     push @m, "\n";
  2039.  
  2040.     return join '', @m;
  2041.     }
  2042.  
  2043.  
  2044.     my($linkcmd,@staticopts,@staticpkgs,$extralist,$target,$targdir,$libperldir);
  2045.  
  2046.     # The front matter of the linkcommand...
  2047.     $linkcmd = join ' ', $Config{'ld'},
  2048.         grep($_, @Config{qw(large split ldflags ccdlflags)});
  2049.     $linkcmd =~ s/\s+/ /g;
  2050.  
  2051.     # Which *.olb files could we make use of...
  2052.     local(%olbs);
  2053.     $olbs{$self->{INST_ARCHAUTODIR}} = "$self->{BASEEXT}\$(LIB_EXT)";
  2054.     require File::Find;
  2055.     File::Find::find(sub {
  2056.     return unless m/\Q$self->{LIB_EXT}\E$/;
  2057.     return if m/^libperl/;
  2058.  
  2059.     if( exists $self->{INCLUDE_EXT} ){
  2060.         my $found = 0;
  2061.         my $incl;
  2062.         my $xx;
  2063.  
  2064.         ($xx = $File::Find::name) =~ s,.*?/auto/,,;
  2065.         $xx =~ s,/?$_,,;
  2066.         $xx =~ s,/,::,g;
  2067.  
  2068.         # Throw away anything not explicitly marked for inclusion.
  2069.         # DynaLoader is implied.
  2070.         foreach $incl ((@{$self->{INCLUDE_EXT}},'DynaLoader')){
  2071.             if( $xx eq $incl ){
  2072.                 $found++;
  2073.                 last;
  2074.             }
  2075.         }
  2076.         return unless $found;
  2077.     }
  2078.     elsif( exists $self->{EXCLUDE_EXT} ){
  2079.         my $excl;
  2080.         my $xx;
  2081.  
  2082.         ($xx = $File::Find::name) =~ s,.*?/auto/,,;
  2083.         $xx =~ s,/?$_,,;
  2084.         $xx =~ s,/,::,g;
  2085.  
  2086.         # Throw away anything explicitly marked for exclusion
  2087.         foreach $excl (@{$self->{EXCLUDE_EXT}}){
  2088.             return if( $xx eq $excl );
  2089.         }
  2090.     }
  2091.  
  2092.     $olbs{$ENV{DEFAULT}} = $_;
  2093.     }, grep( -d $_, @{$searchdirs || []}));
  2094.  
  2095.     # We trust that what has been handed in as argument will be buildable
  2096.     $static = [] unless $static;
  2097.     @olbs{@{$static}} = (1) x @{$static};
  2098.  
  2099.     $extra = [] unless $extra && ref $extra eq 'ARRAY';
  2100.     # Sort the object libraries in inverse order of
  2101.     # filespec length to try to insure that dependent extensions
  2102.     # will appear before their parents, so the linker will
  2103.     # search the parent library to resolve references.
  2104.     # (e.g. Intuit::DWIM will precede Intuit, so unresolved
  2105.     # references from [.intuit.dwim]dwim.obj can be found
  2106.     # in [.intuit]intuit.olb).
  2107.     for (sort keys %olbs) {
  2108.     next unless $olbs{$_} =~ /\Q$self->{LIB_EXT}\E$/;
  2109.     my($dir) = $self->fixpath($_,1);
  2110.     my($extralibs) = $dir . "extralibs.ld";
  2111.     my($extopt) = $dir . $olbs{$_};
  2112.     $extopt =~ s/$self->{LIB_EXT}$/.opt/;
  2113.     if (-f $extralibs ) {
  2114.         open LIST,$extralibs or warn $!,next;
  2115.         push @$extra, <LIST>;
  2116.         close LIST;
  2117.     }
  2118.     if (-f $extopt) {
  2119.         open OPT,$extopt or die $!;
  2120.         while (<OPT>) {
  2121.         next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
  2122.         # ExtUtils::Miniperl expects Unix paths
  2123.         (my($pkg) = "$1_$1$self->{LIB_EXT}") =~ s#_*#/#g;
  2124.         push @staticpkgs,$pkg;
  2125.         }
  2126.         push @staticopts, $extopt;
  2127.     }
  2128.     }
  2129.  
  2130.     $target = "Perl.Exe" unless $target;
  2131.     ($shrtarget,$targdir) = fileparse($target);
  2132.     $shrtarget =~ s/^([^.]*)/$1Shr/;
  2133.     $shrtarget = $targdir . $shrtarget;
  2134.     $target = "Perlshr.$Config{'dlext'}" unless $target;
  2135.     $tmp = "[]" unless $tmp;
  2136.     $tmp = $self->fixpath($tmp,1);
  2137.     if (@$extra) {
  2138.     $extralist = join(' ',@$extra);
  2139.     $extralist =~ s/[,\s\n]+/, /g;
  2140.     }
  2141.     else { $extralist = ''; }
  2142.     if ($libperl) {
  2143.     unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) {
  2144.         print STDOUT "Warning: $libperl not found\n";
  2145.         undef $libperl;
  2146.     }
  2147.     }
  2148.     unless ($libperl) {
  2149.     if (defined $self->{PERL_SRC}) {
  2150.         $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}");
  2151.     } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) {
  2152.     } else {
  2153.         print STDOUT "Warning: $libperl not found
  2154.     If you're going to build a static perl binary, make sure perl is installed
  2155.     otherwise ignore this warning\n";
  2156.     }
  2157.     }
  2158.     $libperldir = $self->fixpath((fileparse($libperl))[1],1);
  2159.  
  2160.     push @m, '
  2161. # Fill in the target you want to produce if it\'s not perl
  2162. MAP_TARGET    = ',$self->fixpath($target),'
  2163. MAP_SHRTARGET = ',$self->fixpath($shrtarget),"
  2164. MAP_LINKCMD   = $linkcmd
  2165. MAP_PERLINC   = ", $perlinc ? map('"$_" ',@{$perlinc}) : '','
  2166. # We use the linker options files created with each extension, rather than
  2167. #specifying the object files directly on the command line.
  2168. MAP_STATIC    = ',@staticopts ? join(' ', @staticopts) : '','
  2169. MAP_OPTS    = ',@staticopts ? ','.join(',', map($_.'/Option', @staticopts)) : '',"
  2170. MAP_EXTRA     = $extralist
  2171. MAP_LIBPERL = ",$self->fixpath($libperl),'
  2172. ';
  2173.  
  2174.  
  2175.     push @m,'
  2176. $(MAP_SHRTARGET) : $(MAP_LIBPERL) $(MAP_STATIC) ',"${libperldir}Perlshr_Attr.Opt",'
  2177.     $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_OPTS), $(MAP_EXTRA), $(MAP_LIBPERL) ',"${libperldir}Perlshr_Attr.Opt",'
  2178. $(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmp}perlmain\$(OBJ_EXT) ${tmp}PerlShr.Opt",'
  2179.     $(MAP_LINKCMD) ',"${tmp}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option
  2180.     ',$self->{NOECHO},'Write Sys$Output "To install the new ""$(MAP_TARGET)"" binary, say"
  2181.     ',$self->{NOECHO},'Write Sys$Output "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
  2182.     ',$self->{NOECHO},'Write Sys$Output "To remove the intermediate files, say
  2183.     ',$self->{NOECHO},'Write Sys$Output "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) map_clean"
  2184. ';
  2185.     push @m,'
  2186. ',"${tmp}perlmain.c",' : $(MAKEFILE)
  2187.     ',$self->{NOECHO},'$(PERL) $(MAP_PERLINC) -e "use ExtUtils::Miniperl; writemain(qw|',@staticpkgs,'|)" >$(MMS$TARGET)
  2188. ';
  2189.  
  2190.     push @m, q[
  2191. # More from the 255-char line length limit
  2192. doc_inst_perl :
  2193.     ].$self->{NOECHO}.q[$(PERL) -e "print 'Perl binary $(MAP_TARGET)|'" >.MM_tmp
  2194.     ].$self->{NOECHO}.q[$(PERL) -e "print 'MAP_STATIC|$(MAP_STATIC)|'" >>.MM_tmp
  2195.     ].$self->{NOECHO}.q[$(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp
  2196.     ].$self->{NOECHO}.q[$(PERL) -e "print 'MAP_LIBPERL|$(MAP_LIBPERL)|'" >>.MM_tmp
  2197.     $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
  2198.     ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp;
  2199. ];
  2200.  
  2201.     push @m, "
  2202. inst_perl : pure_inst_perl doc_inst_perl
  2203.     \$(NOOP)
  2204.  
  2205. pure_inst_perl : \$(MAP_TARGET)
  2206.     $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1),"
  2207.     $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"
  2208.  
  2209. clean :: map_clean
  2210.     \$(NOOP)
  2211.  
  2212. map_clean :
  2213.     \$(RM_F) ${tmp}perlmain\$(OBJ_EXT) ${tmp}perlmain.c \$(MAKEFILE)
  2214.     \$(RM_F) ${tmp}PerlShr.Opt \$(MAP_TARGET)
  2215. ";
  2216.  
  2217.     join '', @m;
  2218. }
  2219.   
  2220. =item ext (specific)
  2221.  
  2222. Stub routine standing in for C<ExtUtils::LibList::ext> until VMS
  2223. support is added to that package.
  2224.  
  2225. =cut
  2226.  
  2227. sub ext {
  2228.     my($self) = @_;
  2229.     '','','';
  2230. }
  2231.  
  2232. # --- Output postprocessing section ---
  2233.  
  2234. =item nicetext (override)
  2235.  
  2236. Insure that colons marking targets are preceded by space, in order
  2237. to distinguish the target delimiter from a colon appearing as
  2238. part of a filespec.
  2239.  
  2240. =cut
  2241.  
  2242. sub nicetext {
  2243.  
  2244.     my($self,$text) = @_;
  2245.     $text =~ s/([^\s:])(:+\s)/$1 $2/gs;
  2246.     $text;
  2247. }
  2248.  
  2249. 1;
  2250.  
  2251. __END__
  2252.  
  2253.